package zenupdaterapp.tasks;

import java.io.IOException;
import java.util.Properties;

import zenupdaterapp.customization.Customization;
import zenupdaterapp.misc.Log;
import zenupdaterapp.service.UpdateCheckService;
import zenupdaterapp.ui.R;
import zenupdaterapp.utils.Preferences;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.Toast;

public class AppUpdateCheckTask {
    public static class CheckerThread extends Thread {

		private Context mContext;
		private Boolean showDebugOutput = false;

		public CheckerThread(Context context, Boolean _showDebugOutput) {
			showDebugOutput = _showDebugOutput;
			mContext = context;
		}

		@Override
		public void run() {
			try {
				sleep(1500);
			} catch (InterruptedException e) {
				if (showDebugOutput) Log.e(TAG, "IEx while checking for updates", e);
			}
			checkForUpdate(mContext, showDebugOutput);
		}
	}
	
	private static final String TAG = "AppUpdateCheckTask";
	
	/**
	 * Period between checks. Currently set to 24 hours (in milliseconds).
	 */
	private static long CHECK_PERIOD = 24 * 3600 * 1000;
	
	public static void checkForUpdateInThread(final Context context, Boolean _showDebugOutput) {
		new CheckerThread(context, _showDebugOutput).start();
	}

	public static void checkForUpdate(final Context context, Boolean _showDebugOutput) {
		int currentVersion = -1;
		try {
			PackageInfo pi = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			currentVersion = pi.versionCode;
			if (_showDebugOutput) Log.d(TAG, "Package name: " + pi.packageName);
			if (_showDebugOutput) Log.d(TAG, "Version name: " + pi.versionName);
			if (_showDebugOutput) Log.d(TAG, "Version code: " + pi.versionCode);
			if (_showDebugOutput) Log.d(TAG, "Current version: " + currentVersion);
		} catch (NameNotFoundException e) {
			if (_showDebugOutput) Log.e(TAG, "NameNotFoundException", e);
		}
		
		String txtlink = Customization.APP_UPDATE_URL
		+ context.getPackageName() + ".txt";
		
		Preferences prefs = new Preferences(context);
		Properties checker = null;
		try {
			checker = UpdateCheckService.queryForProperties(txtlink);
		} catch (IOException e) {
			if (_showDebugOutput) Log.e(TAG, "IOEx while checking for updates", e);
		}
		if (checker != null && checker.containsKey("Version")) {
			int latestVersion = Integer.parseInt(checker.getProperty("Version"));
			String comment = checker.getProperty("Comment", "");
			final String dllink = checker.getProperty("DownloadLink", "");
			final String datawipe = checker.getProperty("DataWipe", "");
		
			if (currentVersion > 0 && latestVersion > 0
					&& currentVersion < latestVersion) {
					AppUpdateCheckTask.openUpdateDialog(context, prefs, latestVersion, dllink, comment, datawipe);
			} else {
				if (_showDebugOutput) Log.d(TAG, "App Version up-to-date");
			}
		}
	}
	
	private static void openUpdateDialog(final Context context, final Preferences prefs, final int version, final String dllink, final String comment, final String datawipe) {
		Looper.prepare();
		final Long Version = Long.valueOf(version);
		String msg = context.getString(R.string.app_update_available,
				comment);
		(new AlertDialog.Builder(context).setMessage(msg)
				.setTitle(R.string.app_update_available_title)
				.setIcon(android.R.drawable.ic_dialog_alert)
				.setPositiveButton(R.string.app_update_available_yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						//Download New App Version, Set Data Wipe Boolean & Set Stored Version
						prefs.setAppDataWipePref(datawipe);
						prefs.setStoredVersion(Version);
                        Intent i = new Intent(Intent.ACTION_VIEW);
                        i.setData(Uri.parse(dllink));
                        context.startActivity(i);
                        dialog.dismiss();
					}
				})
				.setNegativeButton(R.string.app_update_available_no,
				new OnClickListener() {
					public void onClick(DialogInterface arg0, int arg1) {
						Toast.makeText(context,
								R.string.app_update_toast_no_click,
								Toast.LENGTH_LONG).show();	
					}
				})).show();
		Looper.loop();
	}
	
	private static boolean skipCheck(final Context context, Preferences prefs) {
		long currentTime = System.currentTimeMillis();
		long lastCheckTime = prefs.getLastAppCheckTime();
		if (lastCheckTime > 0 && currentTime - lastCheckTime < CHECK_PERIOD) {
			// can skip Update test
			return true;
		}
		// Do the check (don't skip).
		return false;
	}

	public static void StartCheck(final Context context, Boolean _showDebugOutput) {
		Preferences prefs = new Preferences(context);
		if (skipCheck(context, prefs)) {
			// Don't need to check too often.
			if (_showDebugOutput) Log.i(TAG, "Skipping App Update Check > 24hrs");
			return;
		}
		// Remember the current time in shared preferences.
		prefs.setAppCheckTime();

		AppUpdateCheckTask.checkForUpdateInThread(context, _showDebugOutput);
	}
	
	public static void ManualCheck(final Context context, final Boolean _showDebugOutput) {
    final ProgressDialog dialog = ProgressDialog.show(context, context.getString(R.string.app_update_pd_title), 
    		context.getString(R.string.app_update_pd_summary), true);
    		dialog.setCancelable(true);
	final Handler ToastHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.arg1 != 0) {
				dialog.dismiss();
                Toast.makeText(context, msg.arg1, Toast.LENGTH_LONG).show();  
			} else {
				dialog.dismiss();
				if (msg.arg2 != 0) {
					dialog.dismiss();
	                Toast.makeText(context, msg.arg2, Toast.LENGTH_LONG).show();
				}
            }
		}
	};
	
	Thread checkUpdate = new Thread() {
		public void run() {
			int currentVersion = -1;
			try {
				PackageInfo pi = context.getPackageManager().getPackageInfo(
						context.getPackageName(), 0);
				currentVersion = pi.versionCode;
				if (_showDebugOutput) Log.d(TAG, "Package name: " + pi.packageName);
				if (_showDebugOutput) Log.d(TAG, "Version name: " + pi.versionName);
				if (_showDebugOutput) Log.d(TAG, "Version code: " + pi.versionCode);
				if (_showDebugOutput) Log.d(TAG, "Current version: " + currentVersion);
			} catch (NameNotFoundException e) {
				if (_showDebugOutput) Log.e(TAG, "NameNotFoundException", e);
			}
			
			String txtlink = Customization.APP_UPDATE_URL
			+ context.getPackageName() + ".txt";
			
			Preferences prefs = new Preferences(context);
			Properties checker = null;
			try {
				checker = UpdateCheckService.queryForProperties(txtlink);
			} catch (IOException e) {
				if (_showDebugOutput) Log.e(TAG, "IOEx while checking for updates", e);
				ToastHandler.sendMessage(ToastHandler.obtainMessage(0, R.string.app_update_toast_error, 0));
			}
			if (checker != null && checker.containsKey("Version")) {
				int latestVersion = Integer.parseInt(checker.getProperty("Version"));
				String comment = checker.getProperty("Comment", "");
				final String dllink = checker.getProperty("DownloadLink", "");
				final String datawipe = checker.getProperty("DataWipe", "");
			
				if (currentVersion > 0 && latestVersion > 0
						&& currentVersion < latestVersion) {
						ToastHandler.sendEmptyMessage(0);
						AppUpdateCheckTask.openUpdateDialog(context, prefs, latestVersion, dllink, comment, datawipe);
				} else {
					if (_showDebugOutput) Log.d(TAG, "App Version up-to-date");
						ToastHandler.sendMessage(ToastHandler.obtainMessage(0, R.string.app_update_toast_no_update, 0));
					}
				}
			}
		};
		checkUpdate.start();
	}
}